package com.example.demo.scheduledtask;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.example.demo.common.Constant;
import com.example.demo.config.ErpConfig;
import com.example.demo.mapper.PoMpsinfoMapper;
import com.example.demo.mapper.WmsPurchaseMapper;
import com.example.demo.mapper.WmsPurchaseNewMapper;
import com.example.demo.utils.SoapXmlUtil;
import com.example.demo.vo.GenIqcDataVo;
import com.example.demo.vo.SlCallbackListVo;
import com.example.demo.vo.XmlResp;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author : Zhang.yt
 * @date : 2024/7/29
 */
@Component
@Slf4j
@DS("wms")
public class GenIqcData {
    @Resource
    private WmsPurchaseNewMapper wmsPurchaseNewMapper;

    @Autowired
    private SoapXmlUtil soapXmlUtil;

    @Autowired
    private PoMpsinfoMapper poMpsinfoMapper;

    @Resource
    private ErpConfig erpConfig;

    @Resource
    private WmsPurchaseMapper wmsPurchaseMapper;



    /**
     * 收货检验回写
     */
    @Scheduled(fixedDelay = 7 * 1000)//开启定时同步
    //@Async(value = "taskExecutor")
    public void genIqcData() {
        GenIqcDataVo genIqcDataNew = wmsPurchaseNewMapper.getGenIqcDataNew();

        if (ObjectUtil.isEmpty(genIqcDataNew) || ObjectUtils.isEmpty(genIqcDataNew.getQcbaud001())) {
            log.info("未查询到收货检验回写数据，修改报错数据重新过账");
            wmsPurchaseMapper.genIqcDataLose();
            return;
        }
        //设置公共请求信息
        String checkNo = genIqcDataNew.getQcbaud001();
        try {
                        //超过20秒未获取到锁就退出
//            if (!lock.tryLock(20, TimeUnit.SECONDS)) {
//                return;
//            }
            //委外情况
            Integer genIqcDataNewList = wmsPurchaseNewMapper.getGenIqcDataNewList(genIqcDataNew.getQcbaud001());
            //查询关联的报检单数据
            List<SlCallbackListVo> slCallbackList = poMpsinfoMapper.getSlCallbackList(genIqcDataNew.getSlno(), genIqcDataNew.getPmdt001(), genIqcDataNew.getMcode());
            if (CollUtil.isEmpty(slCallbackList)) {
                if (genIqcDataNew.getTc().equals(1)) {
                    wmsPurchaseNewMapper.updateStCheckTcOpflg(genIqcDataNew.getQcbaud001(), 2, "未获取到收货回写数据,检验单未回写");
                } else {
                    wmsPurchaseNewMapper.updateStCheckOpflg(genIqcDataNew.getQcbaud001(), 2, "未获取到收货回写数据,检验单未回写");
                }
                return;
            }
            //由于可能会返回多个单号保存会写记录
            List<GenIqcDataVo> genIqcDataVoList = new ArrayList<>();

            if (genIqcDataNewList > 1) {
                slCallbackList = poMpsinfoMapper.getSlCallbackListWw(genIqcDataNew.getSlno(), genIqcDataNew.getPmdt001(), genIqcDataNew.getMcode(), checkNo);
                //todo 委外数据全部按合格处理
                BigDecimal genIqcDataNewWw = wmsPurchaseNewMapper.getGenIqcDataNewWw(checkNo);
                computeSlCallbackListWw(genIqcDataNewWw, slCallbackList, genIqcDataVoList, checkNo, genIqcDataNew.getQcba900());
            } else {
                //根据回填数据计算项次项序
//            List<List<SlCallbackListVo>> combinations = findCombinations(slCallbackList, genIqcDataNew.getQcba008());
//            if (CollUtil.isEmpty(combinations)){
//                wmsPurchaseNewMapper.updateStCheckTcOpflg(genIqcDataNew.getQcbaud001(), 2, "计算数据异常");
//                return;
//            }
                //如果合格数量>可回写数量，报错
                BigDecimal pmdt020 = slCallbackList.stream().map(SlCallbackListVo::getPmdt020).reduce(BigDecimal.ZERO, BigDecimal::add);
                BigDecimal pmdt053 = slCallbackList.stream().map(SlCallbackListVo::getPmdt053).reduce(BigDecimal.ZERO, BigDecimal::add);
                BigDecimal subtract = pmdt020.subtract(pmdt053);
                if (genIqcDataNew.getQcba023().compareTo(subtract) > 0) {
                    if (genIqcDataNew.getTc().equals(1)) {
                        wmsPurchaseNewMapper.updateStCheckTcOpflg(genIqcDataNew.getQcbaud001(), 2, "本次回写数量:" + genIqcDataNew.getQcba023() + "大于可回写数量:" + subtract + ",请确认");
                    } else {
                        wmsPurchaseNewMapper.updateStCheckOpflg(genIqcDataNew.getQcbaud001(), 2, "本次回写数量:" + genIqcDataNew.getQcba023() + "大于可回写数量:" + subtract + ",请确认");
                    }
                    return;
                }
                genIqcDataNew.setActionType(Constant.ActionType_I);
                genIqcDataNew.setQcbadocno(Constant.PMDSDOCNO_3433);
                genIqcDataNew.setQcbasite(Constant.PMDSSITE_AMA);
                //数据计算
                computeSlCallbackList(genIqcDataNew, slCallbackList, genIqcDataVoList);
            }
            if (genIqcDataVoList.size() == 1) {
                GenIqcDataVo genIqcDataVo = genIqcDataVoList.get(0);
                //获取回写json
                String resMessage = soapXmlUtil.getSoapXml("GenIqcData", "qcba_t", genIqcDataVo);
//                String replaceAll = resMessage.replaceAll("value='100.00000000'", "value='40.00000000'");

                sendIqcMessageNew(genIqcDataVo.getQcba001(), genIqcDataNew, checkNo, resMessage, 1);
            } else {
                //获取回写json
                String resMessage = soapXmlUtil.getSoapXmlList("GenIqcData", "qcba_t", genIqcDataVoList);
                sendIqcMessageNew(genIqcDataVoList.get(0).getQcba001(), genIqcDataNew, checkNo, resMessage, genIqcDataVoList.size());
            }
        } catch (Exception e) {
            if (genIqcDataNew.getTc().equals(1)) {
                wmsPurchaseNewMapper.updateStCheckTcOpflg(checkNo, 2, "非常见的数据处理问题，请联系开发人员处理");
            } else {
                wmsPurchaseNewMapper.updateStCheckOpflg(checkNo, 2, "非常见的数据处理问题，请联系开发人员处理");
            }
            e.printStackTrace();
        }
//        finally {
//            log.error("finally释放锁{}", this.getClass().getName());
//            if (ObjectUtil.isNotEmpty(lock) && lock.isHeldByCurrentThread()) {
//                lock.unlock();
//            }
//        }
    }


    private void sendIqcMessageNew(String qcba001, GenIqcDataVo genIqcDataNew, String checkNo, String resMessage, int size) throws InterruptedException {
        log.info("soapIQC质检请求:->{}", resMessage);
        if (genIqcDataNew.getTc().equals(1)) {
            wmsPurchaseNewMapper.updateStCheckTcOpflg(checkNo, 3, "erp待返回");
        } else {
            wmsPurchaseNewMapper.updateStCheckOpflg(checkNo, 3, "erp待返回");
        }
        //获取回写json
        //发送soap消息，并解析结果
        String result;
        try {
            result = soapXmlUtil.sendSoapMessageNew(resMessage, erpConfig.getUrl());
        } catch (Exception e) {
            result = soapXmlUtil.sendSoapMessageNew(resMessage, erpConfig.URL2);
        }
//        if (size >= 200) {
//            Thread.sleep(150 * 1000);
//        } else if (size >= 100) {
//            Thread.sleep(90 * 1000);
//        } else if (size >= 50) {
//            Thread.sleep(60 * 1000);
//        } else if (size >= 30) {
//            Thread.sleep(20 * 1000);
//        } else if (size >= 10) {
//            Thread.sleep(10 * 1000);
//        } else if (size >= 5) {
//            Thread.sleep(5 * 1000);
//        }
        //每一次调用等待3秒钟时间返回数据--防止回写成功后数据出现异常
        log.info("soap接口IQC质检返回:->{}", result);
        XmlResp xmlResp = soapXmlUtil.analysisXml(result);
        //成功
        if (xmlResp.getCode().equals("0")) {
            if (genIqcDataNew.getTc().equals(1)) {
                wmsPurchaseNewMapper.updateStCheckTcOpflg(checkNo, 1, xmlResp.getData().get("qcbadocno"));
            } else {
                wmsPurchaseNewMapper.updateStCheckOpflg(checkNo, 1, xmlResp.getData().get("qcbadocno"));
            }
            //更新回写单据可入库量
//                poMpsinfoMapper.syncPurchaseReceiptDetails();
            wmsPurchaseNewMapper.updatePurchaseReceiptDetails(qcba001);
        } else {
            if (genIqcDataNew.getTc().equals(1)) {
                wmsPurchaseNewMapper.updateStCheckTcOpflg(checkNo, 2, xmlResp.getMessage());
            } else {
                wmsPurchaseNewMapper.updateStCheckOpflg(checkNo, 2, xmlResp.getMessage());
            }
        }
    }

    private void computeSlCallbackListWw(BigDecimal qcba008, List<SlCallbackListVo> slCallbackList, List<GenIqcDataVo> genIqcDataVoList, String checkNo, String qcba900) {
        Date date = new Date();
        //由于数量是合并，需要计算后回写
        for (SlCallbackListVo slCallbackListVo : slCallbackList) {
            GenIqcDataVo genIqcDataVoReq = new GenIqcDataVo();
            //防止单号重复这里回写单号为：质检单号 + 报检项次
            genIqcDataVoReq.setQcbaud001(checkNo + '-' + slCallbackListVo.getPmdtseq());
            genIqcDataVoReq.setQcba001(slCallbackListVo.getPmdsdocno());
            genIqcDataVoReq.setQcba002(slCallbackListVo.getPmdtseq());
            genIqcDataVoReq.setActionType(Constant.ActionType_I);
            genIqcDataVoReq.setQcbadocno(Constant.PMDSDOCNO_3433);
            genIqcDataVoReq.setQcbasite(Constant.PMDSSITE_AMA);
            genIqcDataVoReq.setQcbadocdt(date);
            genIqcDataVoReq.setQcba900(qcba900);
            //剩余可收数量
            BigDecimal subtract = slCallbackListVo.getPmdt020().subtract(slCallbackListVo.getPmdt053());
            //合格： 合格数量>收料数量:收料数量 else 合格数量
            if (qcba008.compareTo(subtract) > 0) {
                //收料数量大于等于本项次的数量
                genIqcDataVoReq.setQcba008(subtract);
                qcba008 = qcba008.subtract(subtract);
                genIqcDataVoReq.setQcba023(subtract);
                genIqcDataVoReq.setQcba027(BigDecimal.ZERO);
            } else {
                genIqcDataVoReq.setQcba008(qcba008);
                genIqcDataVoReq.setQcba023(qcba008);
                genIqcDataVoReq.setQcba027(BigDecimal.ZERO);
                qcba008 = BigDecimal.ZERO;
            }
            genIqcDataVoList.add(genIqcDataVoReq);
            if (qcba008.compareTo(BigDecimal.ZERO) == 0) {
                break;
            }
        }
    }

    private void computeSlCallbackList(GenIqcDataVo genIqcDataNew, List<SlCallbackListVo> slCallbackList, List<GenIqcDataVo> genIqcDataVoList) {
        //合格数量
        BigDecimal qcba023 = genIqcDataNew.getQcba023();
        if (qcba023.compareTo(new BigDecimal(0E-8)) == 0) {
            qcba023 = BigDecimal.ZERO;
        }
        //不合格数量
        BigDecimal qcba027 = genIqcDataNew.getQcba027();
        //收料数量
        BigDecimal qcba008 = genIqcDataNew.getQcba008();
        //非特采时 收料数量 != 合格数量时 按合格数量收料
        if (qcba008.compareTo(qcba023) != 0 && genIqcDataNew.getTc().equals(0)) {
            qcba008 = qcba023;
        }
        //特采时不合格数 = 收料数量 - 合格数量
        if (genIqcDataNew.getTc().equals(1)) {
            qcba027 = qcba008.subtract(qcba023);
        }

        if (slCallbackList.size() > 1) {
            //由于数量是合并，需要计算后回写
            for (SlCallbackListVo slCallbackListVo : slCallbackList) {
                GenIqcDataVo genIqcDataVoReq = BeanUtil.copyProperties(genIqcDataNew, GenIqcDataVo.class);
                //防止单号重复这里回写单号为：质检单号 + 报检项次
                if (genIqcDataNew.getTc() == 1) {
                    genIqcDataVoReq.setQcbaud001(genIqcDataVoReq.getQcbaud001() + "-tc-" + slCallbackListVo.getPmdtseq());
                } else {
                    genIqcDataVoReq.setQcbaud001(genIqcDataVoReq.getQcbaud001() + '-' + slCallbackListVo.getPmdtseq());
                }
                genIqcDataVoReq.setQcba900(genIqcDataNew.getQcba900());
                genIqcDataVoReq.setQcba001(slCallbackListVo.getPmdsdocno());
                genIqcDataVoReq.setQcba002(slCallbackListVo.getPmdtseq());

                //剩余可收数量 收料数量-允收数量-验退数量
                BigDecimal subtract = slCallbackListVo.getPmdt020().subtract(slCallbackListVo.getPmdt053()).subtract(slCallbackListVo.getPmdt055());
                if (BigDecimal.ZERO.compareTo(subtract) > 0) {
                    continue;
                }
                //合格： 合格数量>收料数量:收料数量 else 合格数量
                if (qcba008.compareTo(subtract) > 0) {
                    //收料数量大于等于本项次的数量
                    genIqcDataVoReq.setQcba008(subtract);
                    qcba008 = qcba008.subtract(subtract);
                    genIqcDataVoReq.setQcba023(subtract);
                    genIqcDataVoReq.setQcba027(BigDecimal.ZERO);
                } else {
                    genIqcDataVoReq.setQcba008(qcba008);
                    genIqcDataVoReq.setQcba023(qcba008);
                    genIqcDataVoReq.setQcba027(BigDecimal.ZERO);
                    qcba008 = BigDecimal.ZERO;
                }
                genIqcDataVoList.add(genIqcDataVoReq);
                if (qcba008.compareTo(BigDecimal.ZERO) == 0) {
                    break;
                }
            }
        } else {
            SlCallbackListVo slCallbackListVo = slCallbackList.get(0);
            genIqcDataNew.setQcba001(slCallbackListVo.getPmdsdocno());
            genIqcDataNew.setQcba002(slCallbackListVo.getPmdtseq());
            genIqcDataNew.setQcba008(qcba008);
            genIqcDataNew.setQcba027(qcba027);
            genIqcDataNew.setQcba900(genIqcDataNew.getQcba900());
//            genIqcDataNew.setQcba008(slCallbackListVo.getPmdt020());
            if (genIqcDataNew.getTc() == 1) {
                genIqcDataNew.setQcbaud001(genIqcDataNew.getQcbaud001() + "-tc-" + slCallbackListVo.getPmdtseq() + '-');
            } else {
                genIqcDataNew.setQcbaud001(genIqcDataNew.getQcbaud001() + '-' + slCallbackListVo.getPmdtseq() + '-');
            }
            genIqcDataVoList.add(genIqcDataNew);
        }

        //计算后为空则不回写
        if (CollUtil.isEmpty(genIqcDataVoList)) {
            wmsPurchaseNewMapper.updateStCheckTcOpflg(genIqcDataNew.getQcbaud001(), 2, "非常见的数据处理问题，请联系开发人员处理");
            return;
        } else {
            //整单改为带返回状态防止下一次查询到该数据
            if (genIqcDataNew.getTc().equals(1)) {
                wmsPurchaseNewMapper.updateStCheckTcOpflg(genIqcDataNew.getQcbaud001(), 3, "erp待返回");
            } else {
                wmsPurchaseNewMapper.updateStCheckOpflg(genIqcDataNew.getQcbaud001(), 3, "erp待返回");
            }
        }
        //不合格数量插入
        if (qcba027.compareTo(BigDecimal.ZERO) > 0) {
            for (GenIqcDataVo genIqcDataVo : genIqcDataVoList) {
                if (qcba027.compareTo(genIqcDataVo.getQcba008()) > 0) {
                    //不合格数量大于等于本项次的数量
                    genIqcDataVo.setQcba027(genIqcDataVo.getQcba008());
                    genIqcDataVo.setQcba023(BigDecimal.ZERO);
                    qcba027 = qcba027.subtract(genIqcDataVo.getQcba008());
                } else {
                    genIqcDataVo.setQcba023(genIqcDataVo.getQcba008().subtract(qcba027));
                    genIqcDataVo.setQcba027(qcba027);
                    qcba027 = BigDecimal.ZERO;
                }

                if (genIqcDataVo.getQcba027().compareTo(genIqcDataVo.getQcba023()) == 0) {
                    genIqcDataVo.setQcba023(BigDecimal.ZERO);
                }
                if (qcba027.compareTo(BigDecimal.ZERO) == 0) {
                    break;
                }
            }
        }
    }
}
